package com.wedimob.slideshare.task.io.disk;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import android.content.Context;

import com.wedimob.slideshare.Writer;

public class DefaultWriter implements Writer {

	private Context context;

	public void setContext(Context context) {
		this.context = context;
	}

	private URI getParent(URI uri) {
		try {
			String elemts[] = uri.toString().split("/");
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < elemts.length - 1; i++) {
				if (i > 0)
					sb.append("/");
				sb.append(elemts[i]);
			}
			return new URI(sb.toString());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void createDirIfNecessary(URI uri) {
		try {
			File filedir = new File(getParent(uri).getPath());
			if (!filedir.exists()) {
				int nbAttemp = 0;
				boolean isSuccess = false;
				do {
					if (nbAttemp > 0)
						Thread.sleep(20);

					isSuccess = filedir.mkdirs();
				} while (!isSuccess && nbAttemp < 3);

				if (!isSuccess)
					throw new Exception("Cannot create " + filedir);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void write(byte[] data, URI uri) {
		try {
			createDirIfNecessary(uri);
			FileOutputStream out = new FileOutputStream(new File(uri));
			out.write(data);
			out.close();
		} catch (Exception e) {
			System.err.println(uri + " seems incorrect");
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	@Override
	public void zip(URI src, URI dest) {
		try {
			createDirIfNecessary(dest);
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(
					dest.getPath()));
			zipDir(src.getPath(), zos);
			zos.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void zipDir(String dir2zip, ZipOutputStream zos) {
		try {
			File zipDir = new File(dir2zip);
			String[] dirList = zipDir.list();
			byte[] readBuffer = new byte[2156];
			int bytesIn = 0;
			for (int i = 0; i < dirList.length; i++) {
				File f = new File(zipDir, dirList[i]);
				if (f.isDirectory()) {
					String filePath = f.getPath();
					zipDir(filePath, zos);
					continue;
				}

				FileInputStream fis = new FileInputStream(f);
				ZipEntry anEntry = new ZipEntry(f.getName());
				zos.putNextEntry(anEntry);
				while ((bytesIn = fis.read(readBuffer)) != -1)
					zos.write(readBuffer, 0, bytesIn);
				fis.close();
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void delete(URI dir) {
		try {
			File f = new File(dir);
			if (f.isDirectory()) {
				for (File c : f.listFiles())
					delete(c.toURI());
			}
			if (!f.delete())
				System.err.println("Failed to delete file: " + f);

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void deleteEmpty(URI dir) {
		try {
			File f = new File(dir);
			if (f.isDirectory()) {
				for (File c : f.listFiles())
					deleteEmpty(c.toURI());

				if (f.listFiles().length == 0) {
					f.delete();
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
